# @Time : 2021/4/7 14:36
# @Author : Fioman 
# @Phone : 13149920693
"""
eel_manger:
用来启动eel,浏览器和前端进行通信
"""
import os

import bottle
import bottle.ext.websocket as wbs
import gevent

import settings
import sys
import socket
from eel import browers
from tools.hd_logger import HdLogger

logger = HdLogger()


def start_eel():
    """
    start eel with either production or development configuration
    :return:
    """
    if settings.DEVELOP:
        directory = 'src'
        app = 'chrome'
        page = {
            'port': 8000
        }
        flags = []
    else:
        directory = 'web'
        app = 'chrome-app'
        page = 'index.html'
        flags = []
    settings.WEB_PATH = get_real_path(directory)

    start(page,
          size=(1280, 800),
          options={
              'mode': app,
              'port': 9088,
              'host': 'localhost',
              'chromeFlags': flags
          })


def start(*startUrls, **kwargs):
    """
    打开通信
    :param startUrls:
    :param kwargs:
    :return:
    """
    options = kwargs.pop('options', {})
    if options["port"] == 0:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('localhost', 0))
        options['port'] = sock.getsockname()[1]
        sock.close()
    browers.open_chrome(startUrls, options)

    def run_lambda():
        return bottle.run(host=options['host'],
                          port=options['port'],
                          server=wbs.GeventWebSocketServer,
                          quiet=True)

    gevent.spawn(run_lambda)


def get_real_path(pathName):
    """
    根据目录名字获取真真的目录
    :param pathName:
    :return:
    """
    # 主要是打包之后的路径会存放到sys._MEIPASS目录下
    if getattr(sys, 'frozen', False):
        return os.path.join(sys._MEIPASS, pathName)
    else:
        return os.path.join(settings.BASE_DIR, pathName)


def send_loop(msgQueue, websockets):
    """
    给前端发送消息
    :param msgQueue: 消息队列
    :param websockets: 使用的套接字
    :return:
    """
    while True:
        try:
            if not msgQueue.empty():
                msg = msgQueue.get()
                repeat_send(msg, websockets)
        except Exception as e:
            errorInfo = "in send_loop() error: {}".format(str(e))
            print(errorInfo)
            logger.debug(errorInfo)
        gevent.sleep(0.1)


def repeat_send(msg, websockets):
    """
    重复的发送N次消息,直到消息发送成功为止
    :param msg:
    :param websockets:
    :return:
    """
    attemptTimes = 50
    assert isinstance(msg, type(""))
    for _, ws in websockets:
        for attempt in range(attemptTimes):
            try:
                ws.send(msg)
                break
            except Exception as e:
                ws.send(msg)  # 如果出现异常就重新发送.
                print("in repeat_send() error: {}".format(str(e)))
                logger.debug("in repeat_send() error: {}".format(str(e)))
                gevent.sleep(0.01)
